home *** CD-ROM | disk | FTP | other *** search
- /*
- * $RCSfile: catchSignals.c,v $
- * $Revision: 1.2 $
- * $Date: 1996/05/04 23:51:56 $
- */
- /**********************************************************************
- * EXODUS Database Toolkit Software
- * Copyright (c) 1991 Computer Sciences Department, University of
- * Wisconsin -- Madison
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
- * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.
- * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
- * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * The EXODUS Project Group requests users of this software to return
- * any improvements or extensions that they make to:
- *
- * EXODUS Project Group
- * c/o David J. DeWitt and Michael J. Carey
- * Computer Sciences Department
- * University of Wisconsin -- Madison
- * Madison, WI 53706
- *
- * or exodus@cs.wisc.edu
- *
- * In addition, the EXODUS Project Group requests that users grant the
- * Computer Sciences Department rights to redistribute these changes.
- **********************************************************************/
- #include "queue_consist.h"
- #include "sysdefs.h"
- #include "ess.h"
- #include "checking.h"
- #include "list.h"
- #include "error.h"
- #include "sysdefs.h"
- #include "tid.h"
- #include "pool.h"
- #include "io.h"
- #include "bitvec.h"
- #include "lock.h"
- #include "object.h"
- #include "msgdefs.h"
- #include "disk.h"
- #include "thread.h"
- #include "semaphore.h"
- #include "latch.h"
- #include "bf.h"
- #include "link.h"
- #include "volume.h"
- #include "trace.h"
- #include "msgvector.h"
-
- #include "disk_funcs.h"
- #include "server_util_funcs.h"
- #include "adminmsg.h"
- #include "admin_funcs.h"
-
- #ifdef linux
- #include <bsd/signal.h>
- #endif
-
- static void unexpected(int,int);
- static void quiet(int,int);
- /* export this */ void cont(int,int);
-
- static int mypg;
- static int ppid;
- static int devttyfd;
-
- /* whatever is not included here, doesn't get touched. */
- struct siginfo {
- int sig;
- char *string;
- int error_type;
- void (*sv_handler)(int,int);
- } siginfo[] = {
- { 0, "<none>", TYPE_FATAL, unexpected },
- { SIGHUP, "SIGHUP", TYPE_FATAL, unexpected },
- { SIGINT, "SIGINT", TYPE_QUIET, quiet }, /* ^C */
- { SIGQUIT, "SIGQUIT", TYPE_FATAL, unexpected },
- { SIGILL, "SIGILL", TYPE_FATAL, unexpected },
- { SIGTRAP, "SIGTRAP", TYPE_FATAL, unexpected },
- { SIGIOT, "SIGIOT", TYPE_FATAL, unexpected },
- #ifndef linux
- { SIGEMT, "SIGEMT", TYPE_FATAL, unexpected },
- #endif linux
- { SIGFPE, "SIGFPE", TYPE_FATAL, unexpected },
- { SIGKILL, "SIGKILL", 0, (void (*)(int,int))SIG_DFL },
- { SIGBUS, "SIGBUS", TYPE_FATAL, unexpected },
- { SIGSEGV, "SIGSEGV", TYPE_FATAL, (void (*)(int,int))SIG_DFL }, /* unexpected */
- #ifndef linux
- { SIGSYS, "SIGSYS", TYPE_FATAL, unexpected } ,
- #endif linux
- { SIGPIPE, "SIGPIPE", TYPE_QUIET, quiet }, /* diskproc exited? */
- { SIGALRM, "SIGALRM", 0, (void (*)(int,int))SIG_DFL },
- { SIGTERM, "SIGTERM", 0, (void (*)(int,int))SIG_DFL },
- { SIGURG, "SIGURG", TYPE_FATAL, unexpected },
- { SIGSTOP, "SIGSTOP", 0, (void (*)(int,int))SIG_DFL },
- { SIGTSTP, "SIGTSTP", 0, (void (*)(int,int))SIG_DFL },
- { SIGCONT, "SIGCONT", 0, cont },
- { SIGCHLD, "SIGCHLD", 0, (void (*)(int,int))SIG_DFL },
- { SIGTTIN, "SIGTTIN", 0, cont },
- { SIGTTOU, "SIGTTOU", 0, (void (*)(int,int))SIG_IGN },
- { SIGIO, "SIGIO", TYPE_FATAL, unexpected },
- #ifdef hpux
- { SIGPWR, "SIGPWR", TYPE_FATAL, unexpected },
- /* this signal cannot be caught in HP-UX */
- /*{ _SIGRESERVE, "SIGRESERVE", TYPE_FATAL, unexpected },*/
- #else
- { SIGXCPU, "SIGXCPU", TYPE_FATAL, unexpected },
- { SIGXFSZ, "SIGXFSZ", TYPE_FATAL, unexpected },
- #endif hpux
- { SIGVTALRM,"SIGVTALRM",TYPE_FATAL, unexpected },
- { SIGPROF, "SIGPROF", 0, (void (*)(int,int))SIG_DFL },
- { SIGWINCH, "SIGWINCH", 0, (void (*)(int,int))SIG_DFL },
- #ifndef linux
- { SIGLOST, "SIGLOST", TYPE_FATAL, unexpected },
- #endif linux
- { SIGUSR1, "SIGUSR1", TYPE_FATAL, unexpected },
- { SIGUSR2, "SIGUSR2", TYPE_FATAL, unexpected },
- { 0, 0, 0, 0}
- };
-
- static void
- doit(
- int sig,
- int code
- )
- {
- TRPRINT(TR_INIT, TR_LEVEL_1, ("sig %d, code %d", sig, code));
- if ((siginfo[sig].error_type == TYPE_FATAL) ||
- (siginfo[sig].error_type == TYPE_STOP) ) {
- /* make sure that you can at least use ^C or equivalent */
- unCatchAbortSignal(SIGINT);
- /* for the sake of catching some error in admin_ShutServer */
- unCatchAbortSignal(SIGSEGV);
- unCatchAbortSignal(SIGILL);
- }
- SM_ERROR(siginfo[sig].error_type, esmUNIXSIGNAL);
- } /* doit */
-
- static void
- quiet(
- int sig,
- int code
- )
- {
- /* print message only if tracing is on */
- TRPRINT(TR_INIT, TR_LEVEL_1, ("sig %d, code %d", sig, code));
-
- doit(sig,code);
- }
-
-
- static void
- unexpected(
- int sig,
- int code
- )
- {
- fprintf(stderr, "SERVER : signal %s code %d\n", siginfo[sig].string, code);
- doit(sig,code);
- }
-
- static BOOL
- isbg()
- {
- int ctermpg = 0;
- BOOL result;
-
- if(RunInBackground) /* pretend we are */
- return TRUE;
-
- if(ioctl(devttyfd, TIOCGPGRP, &ctermpg) < 0) {
- if((errno == ENOTTY) || (errno == EOPNOTSUPP)) {
- /* not the controlling terminal - oh well */
- /* since we have no controlling terminal, I guess
- * we had better say that we're in the background!
- */
- return TRUE;
- } else {
- perror("TIOCGPGRP");
- SM_ERROR(TYPE_FATAL, errno);
- }
- }
- result = (ctermpg != mypg);
-
- TRPRINT(TR_CL, TR_LEVEL_1, ("%sground", result?"back":"fore"));
- return result;
- }
-
- static void
- dofg(BOOL reopenstdin, BOOL reattach)
- {
- /* RunInBackground is set by -background or the terminal "background"
- * command and, if set, perpetually overrides all other factors
- */
- if(RunInBackground) return; /* do nothing */
-
- if(reopenstdin) {
- /* reopen stdin - closes whatever it was... */
- TRPRINT(TR_CL, TR_LEVEL_1, ("reopening, old fd %d", fileno(stdin)));
- freopen("/dev/tty", "r", stdin);
- TRPRINT(TR_CL, TR_LEVEL_1, ("reopened, new fd %d", fileno(stdin)));
- /* set close-on-exec */
- if (fcntl(fileno(stdin), F_SETFD, NULL) < 0) {
- SM_ERROR(TYPE_FATAL, errno);
- }
- if(reattach) {
- if(ioctl(devttyfd, TIOCSPGRP, &mypg) < 0) {
- perror("TIOCSPGRP");
- }
- }
- }
- /* restore mask after stdin has a fileno */
- setStdinLink();
- }
-
- void
- dobg(BOOL dodetach)
- {
- if(dodetach) {
- TRPRINT(TR_CL, TR_LEVEL_1, ("detaching, ttyfd %d", devttyfd));
- if(ioctl(devttyfd, TIOCSPGRP, &ppid) < 0) {
- perror("TIOCSPGRP");
- }
- }
- TRPRINT(TR_CL, TR_LEVEL_1, ("stdin fd %d", fileno(stdin)));
- if(fileno(stdin) != -1) {
- /* it's open */
- clearStdinLink();
- fclose(stdin);
- }
- /* now it's closed */
- }
-
- void
- cont(int sig, int unused)
- {
- static int countTTIN = 0;
- TRPRINT(TR_CL, TR_LEVEL_1, ("cont sig %d", sig));
- if( isbg() ) {
- dobg(FALSE); /* already detached */
- } else {
- countTTIN = 0;
- dofg(TRUE, FALSE);
- }
- if(++countTTIN > 4) {
- SM_ERROR(TYPE_FATAL, esmINTERNAL);
- }
- }
-
- void
- startuptty()
- {
- if( isbg() ) {
- clearStdinLink();
- /* its fd is already closed, but we want to
- * clean up the FILE too, so fclose it:
- */
- fclose(stdin);
- } else {
- /* already open, attached */
- setStdinLink();
- }
- TRPRINT(TR_CL, TR_LEVEL_1, ("stdin fd %d", fileno(stdin)));
- }
-
-
- void
- catchSignals()
- {
- extern int errno;
- struct sigvec sv;
- register int i;
-
- TRACE(TR_INIT | TR_CL, TR_LEVEL_1);
- if( (ppid = getppid()) < 0 ) {
- perror("getppid(0)");
- }
- #if defined(hpux) || defined(linux)
- if( (mypg = getpgrp()) < 0 ) {
- perror("getpgrp()");
- }
- #else
- if( (mypg = getpgrp(0)) < 0 ) {
- perror("getpgrp(0)");
- }
- #endif
- if((devttyfd = open("/dev/tty", O_RDONLY, 0))<0) {
- if(errno == ENXIO) {
- /* no such device - that means whoever
- * forked us did a TIOCNOTTY first - gak
- */
- devttyfd = 0;
- /* that's our best guess. and if it's closed,
- * well, c'est la vie. we won't be able to
- * do much.
- */
- } else {
- perror("open dev/tty");
- admin_ShutServer(0);
- }
- }
-
- sv.sv_mask = 0; /* or-ed in with mask for current signal */
- sv.sv_flags = 0; /* don't use sigstack */
-
- for(i=1; i<NSIG; i++) {
-
- if (siginfo[i].sig == 0) {
- break; /* end of list of signals */
- }
-
- /*
- * Cast to no-arg func so it compiles. Maybes someday someone
- * will fix signal.h to declare sv_handler properly.
- */
- #if defined(DOTDOTDOT) || defined(hpux)
- /* Sun C++ defines DOTDOTDOT */
- if((sv.sv_handler = (void (*)(...))siginfo[i].sv_handler)
- == (void (*)(...))SIG_DFL)
- #elif defined(linux)
- if((sv.sv_handler = (__sighandler_t)siginfo[i].sv_handler)
- == SIG_DFL)
- #else
- if((sv.sv_handler = (void (*)())siginfo[i].sv_handler)
- == (void (*)())SIG_DFL)
- #endif
- continue; /* don't bother */
-
- /*
- TRPRINT(TR_INIT | TR_CL, TR_LEVEL_1, ("signal %d gets 0x%x",
- siginfo[i].sig, (void *)(siginfo[i].sv_handler)));
- */
-
- #ifdef hpux
- if(sigvector(siginfo[i].sig, &sv, 0 /* don't care about old vector */) < 0) {
- #else
- if(sigvec(siginfo[i].sig, &sv, 0 /* don't care about old vector */) < 0) {
- #endif hpux
- TRPRINT(TR_INIT, TR_LEVEL_1, ("sigvec failure on sig %d",siginfo[i]));
- SM_ERROR(TYPE_FATAL, errno);
- }
- }
- }
-
- void
- unCatchAbortSignal(
- int sig
- )
- {
- struct sigvec sv;
-
- TRPRINT(TR_INIT, TR_LEVEL_1, ("sig %d", sig));
- sv.sv_mask = 0; /* or-ed in with mask for current signal */
- sv.sv_flags = 0; /* don't use sigstack */
- #if defined(DOTDOTDOT) || defined(hpux)
- /* Sun C++ defines DOTDOTDOT */
- sv.sv_handler = (void (*)(...))SIG_DFL;
- #elif defined(linux)
- sv.sv_handler = SIG_DFL;
- #else
- sv.sv_handler = (void (*)())SIG_DFL;
- #endif
-
- #ifdef hpux
- if(sigvector(sig, &sv, 0 /* don't care about old vector */) < 0) {
- #else
- if(sigvec(sig, &sv, 0 /* don't care about old vector */) < 0) {
- #endif hpux
- perror("sigvec"); /* to avoid loops we don't call SM_ERROR */
- admin_ShutServer(SHUT_ABNORMAL_EXIT | SHUT_DUMP_CORE);
- }
- }
-